<template>
    <div>
        <h4>- Iterator（遍历器），它是一种接口，为各种不同的数据结构提供统一的访问机制</h4>
        <p>任何数据结构只要部署 Iterator 接口，就可以完成遍历操作</p>
        <p>
            Iterator 的遍历过程：
            <ul>
                <li>创建一个指针对象，指向当前数据结构的起始位置</li>
                <li>第一次调用指针对象的next方法，可以将指针指向数据结构的第一个成员</li>
                <li>第二次调用指针对象的next方法，指针就指向数据结构的第二个成员</li>
                <li>不断调用指针对象的next方法，直到它指向数据结构的结束位置</li>
            </ul>
            每一次调用next方法都会返回一个包含value和done两个属性的对象，其中，value属性是当前成员的值，done属性是一个布尔值，表示遍历是否结束
            <code>
    <pre>
        var it = makeIterator(['a', 'b']);

        it.next() // { value: "a", done: false }
        it.next() // { value: "b", done: false }
        it.next() // { value: undefined, done: true }

        function makeIterator(array) {
        var nextIndex = 0;
        return {
            next: function() {
                return nextIndex &lt; array.length ?
                    {value: array[nextIndex++], done: false} :
                    {value: undefined, done: true};
                }
            };
        }
    </pre>
            </code>
        </p>
        <h4>- 默认 Iterator 接口 一种数据结构只要部署了 Iterator 接口，我们就称这种数据结构是“可遍历的”</h4>
        <p>Iterator 接口的目的，就是为所有数据结构，提供了一种统一的访问机制，即for...of循环</p>
        <p>默认的 Iterator 接口部署在数据结构的Symbol.iterator属性中，一个数据结构只要具有Symbol.iterator属性，就可以认为是“可遍历的”</p>
        <p>原生具备 Iterator 接口的数据结构：<b>Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象</b></p>
        <code>let arr = ['a', 'b', 'c']; let iter = arr[Symbol.iterator](); iter.next()// { value: 'a', done: false }...</code>
        <p>!！对象（Object）没有默认部署 Iterator 接口，需自行利用 Symbol.iterator属性 部署</p>
        <p>类似数组的对象部署 Iterator 接口，可以使用Symbol.iterator方法直接引用数组的 Iterator 接口 注意！普通对象部署数组的Symbol.iterator方法，并无效果</p>
        <code>likeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 或者：NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];</code>
        <p>有了遍历器接口，数据结构就可以用for...of 或者 while 循环遍历</p>
        <h4>-字符串的 Iterator 接口 字符串是一个类似数组的对象，也原生具有 Iterator 接口。</h4>
        <h4>- 遍历器对象的 return()，throw()</h4>
        <p>如果for...of循环提前退出（通常是因为出错，或者有break语句），就会调用return方法</p>
        <h4>- for ...of循环  内部调用的是数据结构的Symbol.iterator方法</h4>
        <p>使用范围：数组、Set 和 Map 结构、某些类似数组的对象（比如arguments对象、DOM NodeList 对象）、后文的 Generator 对象，以及字符串</p>
        <ul>
            <li>数组：for...in循环读取键名，for...of循环读取键值；for...of循环调用遍历器接口，数组的遍历器接口只返回具有数字索引的属性</li>
            <li>Set 和 Map 结构：遍历的顺序是按照各个成员被添加进数据结构的顺序；Set 结构遍历时，返回的是一个值，而 Map 结构遍历时，返回的是一个数组，该数组的两个成员分别为当前 Map 成员的键名和键值</li>
            <li>类似数组的对象（字符串、DOM NodeList 对象、arguments对象）：对于字符串来说，会正确识别 32 位 UTF-16 字符；<b>并不是所有类似数组的对象都具有 Iterator 接口，一个简便的解决方法，就是使用Array.from方法将其转为数组。</b></li>
            <li>对象：不能使用for of，必须部署了 Iterator 接口后才能使用；可以这样解决：使用Object.keys方法将对象的键名生成一个数组，然后遍历这个数组；或者使用Generator 函数将对象重新包装</li>
        </ul>
        <h4>- 与其他遍历语法的比较</h4>
        <p>forEach方法 无法中途跳出forEach循环，break命令或return命令都不能奏效</p>
        <p>for...in循环 <b>为遍历对象而设计的，不适用于遍历数组</b> 会将数组的键名（数字）变成 字符串 返回；而且它不仅遍历数字键名，还会遍历手动添加的其他键，甚至包括原型链上的键</p>
        <p>for...of循环 没有for...in那些缺点；可以与break、continue和return配合使用；提供了遍历所有数据结构的统一操作接口</p>
    </div>
</template>

<script>
export default {
    
}
</script>

<style scoped>

</style>